// Kony

#include "AI/Tasks/BTTask_MoveTo8Directions.h"
#include "BehaviorTree/BehaviorTreeComponent.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "AIController.h"
#include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Engine/Engine.h"
#include "DrawDebugHelpers.h"

UBTTask_MoveTo8Directions::UBTTask_MoveTo8Directions()
{
	NodeName = TEXT("Move To 8 Directions");
	
	// 设置黑板键
	BlackboardKey.SelectedKeyName = TEXT("TargetToFollow");
}

void UBTTask_MoveTo8Directions::TickTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds)
{
	// 首先调用父类的TickTask
	Super::TickTask(OwnerComp, NodeMemory, DeltaSeconds);
	
	// 获取AI控制器和Pawn
	AAIController* AIController = OwnerComp.GetAIOwner();
	if (!AIController) return;
	
	APawn* ControlledPawn = AIController->GetPawn();
	if (!ControlledPawn) return;
	
	// 获取黑板和目标
	UBlackboardComponent* BlackboardComp = OwnerComp.GetBlackboardComponent();
	if (!BlackboardComp) return;
	
	AActor* TargetActor = Cast<AActor>(BlackboardComp->GetValueAsObject(BlackboardKey.SelectedKeyName));
	if (!TargetActor) return;
	
	// 计算到目标的方向
	FVector Direction = (TargetActor->GetActorLocation() - ControlledPawn->GetActorLocation()).GetSafeNormal();
	
	// 8方向标准化
	FVector NormalizedDirection = NormalizeTo8Directions(Direction);
	
	// 应用8方向移动
	if (UCharacterMovementComponent* MovementComp = Cast<UCharacterMovementComponent>(ControlledPawn->GetMovementComponent()))
	{
		// 清除之前的移动输入
		ControlledPawn->AddMovementInput(FVector::ZeroVector);
		
		// 应用8方向移动输入
		ControlledPawn->AddMovementInput(NormalizedDirection, 1.0f);
		
		// 调试输出
		static float DebugTimer = 0.0f;
		DebugTimer += DeltaSeconds;
		if (DebugTimer >= 1.0f)
		{
			UE_LOG(LogTemp, Warning, TEXT("8方向移动应用 - 方向: %s"), *NormalizedDirection.ToString());
			DebugTimer = 0.0f;
		}
	}
}

void UBTTask_MoveTo8Directions::OnTaskFinished(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTNodeResult::Type TaskResult)
{
	// 首先调用父类的OnTaskFinished
	Super::OnTaskFinished(OwnerComp, NodeMemory, TaskResult);
	
	// 如果任务成功，应用8方向移动
	if (TaskResult == EBTNodeResult::Succeeded)
	{
		UE_LOG(LogTemp, Warning, TEXT("Move To 8 Directions 任务成功完成"));
	}
}

FVector UBTTask_MoveTo8Directions::NormalizeTo8Directions(const FVector& Direction)
{
	FVector NormalizedDirection = Direction;
	
	// 调试：输出原始方向
	UE_LOG(LogTemp, Warning, TEXT("8方向标准化 - 原始方向: %s"), *Direction.ToString());
	
	// 如果方向向量长度大于阈值，则进行8方向标准化
	if (NormalizedDirection.Size() > 0.1f)
	{
		// 计算方向向量的角度（弧度）
		float Angle = FMath::Atan2(NormalizedDirection.Y, NormalizedDirection.X);
		
		// 将角度转换为度数
		float AngleDegrees = FMath::RadiansToDegrees(Angle);
		
		// 标准化到8个方向（每45度一个方向）
		// 将角度调整到0-360度范围
		if (AngleDegrees < 0) AngleDegrees += 360.0f;
		
		// 计算最接近的8方向角度
		float SnapAngle = FMath::RoundToFloat(AngleDegrees / 45.0f) * 45.0f;
		
		// 调试：输出角度信息
		UE_LOG(LogTemp, Warning, TEXT("8方向标准化 - 原始角度: %.2f°, 标准化角度: %.2f°"), AngleDegrees, SnapAngle);
		
		// 将角度转换回弧度
		float SnapAngleRadians = FMath::DegreesToRadians(SnapAngle);
		
		// 重新计算标准化的方向向量
		NormalizedDirection.X = FMath::Cos(SnapAngleRadians);
		NormalizedDirection.Y = FMath::Sin(SnapAngleRadians);
		NormalizedDirection.Z = 0.0f; // 保持Z轴为0
		
		// 调试：输出标准化后的方向
		UE_LOG(LogTemp, Warning, TEXT("8方向标准化 - 标准化方向: %s"), *NormalizedDirection.ToString());
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("8方向标准化 - 方向向量太小，设为0"));
	}
	
	return NormalizedDirection;
} 